import {
  Button,
  ConfigProvider,
  message,
  Modal,
  Pagination,
  Space,
  Splitter,
  Table,
  Tooltip,
} from "antd";
import type { TableProps } from "antd";
import zhCN from "antd/locale/zh_CN";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useAntdColumnResize } from "react-antd-column-resize";

import { eventClose, eventDel, fetchEventList } from "@/api/Home/home";
import type { EventItem, field, typesitem } from "@/api/Home/type";
import { DigitalEmployeeChoose } from "@/api/Employee/index";
import ProcessingGraph from "@/components/Process-Antv/index";
import ScrollTypeSelector from "@/components/ScrollTypeSelector/index";
import { useDigitalEmployeeStore } from "@/store/employee";
import { usetypesListtotalStore } from "@/store/leftcard";

const DEFAULT_PAGE_SIZE = 6;
const PAGE_SIZE_OPTIONS = ["6", "12"];

const TableBox = () => {
  const [dataList, setDataList] = useState<EventItem[]>([]);
  const [apiFields, setApiFields] = useState<field[]>([]);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [selectedType, setSelectedType] = useState<string>("");

  const [currentPage, setCurrentPage] = useState<number>(1);
  const [pageSize, setPageSize] = useState<number>(DEFAULT_PAGE_SIZE);
  const [totalCount, setTotalCount] = useState<number>(0);

  const [isModalOpen, setIsModalOpen] = useState(false);
  const [currentRow, setCurrentRow] = useState<EventItem | null>(null);
  const [graphKey, setGraphKey] = useState(0);

  const containerRef = useRef<HTMLDivElement>(null);
  const [tableScrollY, setTableScrollY] = useState(0);

  const setDigitalEmployeeData = useDigitalEmployeeStore(
    (state) => state.setDigitalEmployeeData
  );
  const { typesList, gettypetotal } = usetypesListtotalStore();

  const fetchEventListApi = useCallback(
    async (typeName: string, page = 1, size = DEFAULT_PAGE_SIZE) => {
      try {
        const res = await fetchEventList(typeName, page, size);
        if (res && res.data) {
          setDataList(res.data.results);
          setApiFields(res.fields as any);
          setTotalCount(res.data.count);
        }
      } catch (error) {
        console.error("Failed to fetch event list:", error);
        message.error("获取事件列表失败，请稍后重试。");
      }
    },
    []
  );

  const refreshList = useCallback(async () => {
    gettypetotal();
    if (selectedType) {
      await fetchEventListApi(selectedType, currentPage, pageSize);
      setSelectedRowKeys([]);
    }
  }, [selectedType, currentPage, pageSize, fetchEventListApi, gettypetotal]);

  const handleComplete = useCallback(
    async (record: EventItem) => {
      try {
        const res = await eventClose({ id: [Number(record.id)] });
        if (res.code === 1) {
          message.success(res.message);
          refreshList();
        } else {
          message.error(res.message);
        }
      } catch (err) {
        message.error("请求失败，请稍后重试。");
      }
    },
    [refreshList]
  );

  const handleDelete = useCallback(
    (idToDelete: string | number) => {
      Modal.confirm({
        title: "确认删除该数据吗？",
        content: <p>删除后数据将不可恢复，请谨慎操作！</p>,
        okText: "确定",
        cancelText: "取消",
        onOk: async () => {
          try {
            const res = await eventDel({ id: [Number(idToDelete)] });
            if (res.code === 1) {
              message.success(res.message);
              refreshList();
            } else {
              message.error(res.message);
            }
          } catch (err) {
            message.error("删除失败，请稍后重试。");
          }
        },
      });
    },
    [refreshList]
  );

  const handleHeaderAction = useCallback(
    async (actionType: "complete" | "delete") => {
      if (selectedRowKeys.length === 0) {
        message.warning(
          `请先选择要批量${actionType === "complete" ? "完成" : "删除"}的项！`
        );
        return;
      }

      const apiCall = actionType === "complete" ? eventClose : eventDel;
      const successMessage = `批量${
        actionType === "complete" ? "完成" : "删除"
      }成功`;
      const errorMessage = `批量${
        actionType === "complete" ? "完成" : "删除"
      }失败，请稍后重试。`;

      try {
        const res = await apiCall({ id: selectedRowKeys as number[] });
        if (res?.code === 1) {
          message.success(res.message || successMessage);
          refreshList();
        } else {
          message.error(res?.message || errorMessage);
        }
      } catch (err) {
        message.error(errorMessage);
      }
    },
    [selectedRowKeys, refreshList]
  );

  const handleTypeChange = useCallback(
    (item: typesitem) => {
      if (item.name !== selectedType) {
        setSelectedType(item.name);
        setCurrentPage(1);
      }
    },
    [selectedType]
  );

  const handleRowDoubleClick = useCallback((record: EventItem) => {
    setCurrentRow(record);
    setIsModalOpen(true);
  }, []);

  const handlePageChange = useCallback((page: number, size: number) => {
    setCurrentPage(page);
    setPageSize(size);
  }, []);

  const handleReset = useCallback(() => {
    if (typesList.length > 0) {
      setSelectedType(typesList[0].name);
    }
    setCurrentPage(1);
    setPageSize(DEFAULT_PAGE_SIZE);
    setSelectedRowKeys([]);
  }, [typesList]);

  const operationColumn = useMemo(
    () => ({
      title: "操作",
      key: "action",
      align: "center",
      dataIndex: "action",
      fixed: "right",
      width: 120,
      render: (_: any, record: EventItem) => (
        <Space>
          <Button
            size="small"
            type="link"
            onClick={() => handleComplete(record)}
          >
            完成
          </Button>
          <Button
            size="small"
            type="link"
            danger
            onClick={() => handleDelete(record.id)}
          >
            删除
          </Button>
        </Space>
      ),
    }),
    [handleComplete, handleDelete]
  );

  const columns = useMemo<TableProps<EventItem>["columns"]>(() => {
    const dynamicCols = apiFields
      .filter((f) => f.istitle === 1)
      .map((f) => {
        const [key, title] =
          Object.entries(f).find(([k]) => k !== "istitle") || [];
        if (!key) return null;

        return {
          title,
          dataIndex: key,
          key,
          width: 100,
          ellipsis: { showTitle: false },
          render: (value: any) => (
            <Tooltip placement="topLeft" title={String(value)}>
              {String(value)}
            </Tooltip>
          ),
        };
      })
      .filter(Boolean);

    return [...dynamicCols, operationColumn];
  }, [apiFields, operationColumn]);

  const detailFields = useMemo(
    () => apiFields.filter((f) => f.istitle === 0),
    [apiFields]
  );

  const onRowSelectionChange = useCallback((keys: React.Key[]) => {
    setSelectedRowKeys(keys);
  }, []);

  useEffect(() => {
    if (typesList.length > 0 && !selectedType) {
      setSelectedType(typesList[0].name);
    }
  }, [typesList, selectedType]);

  useEffect(() => {
    if (selectedType) {
      fetchEventListApi(selectedType, currentPage, pageSize);
    }
  }, [selectedType, currentPage, pageSize, fetchEventListApi]);

  useEffect(() => {
    const fetchAuxData = async () => {
      try {
        const res = await DigitalEmployeeChoose();
        setDigitalEmployeeData(res.data);
      } catch (error) {
        console.error("Failed to fetch digital employee data:", error);
      }
    };
    fetchAuxData();
  }, [setDigitalEmployeeData]);

  useEffect(() => {
    const computeHeight = () => {
      if (containerRef.current) {
        const containerHeight = containerRef.current.clientHeight;
        setTableScrollY(Math.max(0, containerHeight - 60));
      }
    };

    const observer = new ResizeObserver(computeHeight);
    if (containerRef.current) {
      observer.observe(containerRef.current);
    }

    computeHeight();

    return () => observer.disconnect();
  }, []);

  const { resizableColumns, components, tableWidth } = useAntdColumnResize(
    () => ({ columns }),
    [columns]
  );

  const maxLabelWidth = Math.max(
    ...detailFields.map((field) => {
      const [, label] =
        Object.entries(field).find(([k]) => k !== "istitle") || [];
      return label ? label.length : 0;
    })
  );

  const labelWidthPx = maxLabelWidth * 8 + 40;

  return (
    <div className="h-full flex flex-col max-w-full">
      <div className="text-5 mb-3 mt-2 flex items-center flex-wrap">
        <div className="w-[6px] h-[20px] bg-[#236BFF] mr-2 ml-2.5" />
        <span className="font-bold">调度人工介入事件清单</span>
        <div className="ml-auto space-x-3">
          <Button
            className="custom-button-style"
            type="primary"
            onClick={handleReset}
          >
            重置
          </Button>
          <Button
            className="custom-button-style"
            type="primary"
            onClick={refreshList}
          >
            刷新
          </Button>
          <Button
            className="custom-button-style"
            color="cyan"
            variant="solid"
            onClick={() => handleHeaderAction("complete")}
          >
            批量完成
          </Button>
          <Button
            className="custom-button-style"
            color="danger"
            variant="solid"
            onClick={() => handleHeaderAction("delete")}
          >
            批量删除
          </Button>
        </div>
      </div>

      <div className="bg-white rounded-20 p-5 flex-1 flex flex-col h-full">
        {typesList.length > 0 && (
          <ScrollTypeSelector
            typesList={typesList}
            selectedType={selectedType}
            onTypeChange={handleTypeChange}
          />
        )}

        <div className="flex-1 h-full" ref={containerRef}>
          <Table
            rowKey="id"
            rowSelection={{
              selectedRowKeys,
              onChange: onRowSelectionChange,
            }}
            columns={resizableColumns}
            dataSource={dataList}
            components={components}
            size="small"
            scroll={{ x: tableWidth, y: tableScrollY }}
            pagination={false}
            locale={{
              emptyText: <div className="text-gray-500 py-6">暂无数据</div>,
            }}
            onRow={(record) => ({
              onDoubleClick: () => handleRowDoubleClick(record),
            })}
          />
        </div>

        <div className="mt-auto flex justify-end pt-4">
          <ConfigProvider locale={zhCN}>
            <Pagination
              current={currentPage}
              pageSize={pageSize}
              total={totalCount}
              showSizeChanger
              pageSizeOptions={PAGE_SIZE_OPTIONS}
              showTotal={(total, range) =>
                `第 ${range[0]}-${range[1]} 条 / 共 ${total} 条`
              }
              onChange={handlePageChange}
            />
          </ConfigProvider>
        </div>
      </div>

      <Modal
        title="事件详情"
        open={isModalOpen}
        onOk={() => setIsModalOpen(false)}
        onCancel={() => setIsModalOpen(false)}
        width={900}
        footer={null}
      >
        {currentRow ? (
          <Splitter
            onResizeEnd={() => setGraphKey((k) => k + 1)}
            className="min-h-[500px]"
          >
            <Splitter.Panel
              defaultSize="24%"
              min="20%"
              max="70%"
              className="bg-[#e6e9f3] rounded-8 p-5 space-y-2 overflow-auto"
            >
              {detailFields.map((field, idx) => {
                const [key, label] =
                  Object.entries(field).find(([k]) => k !== "istitle") || [];
                const value = key ? currentRow[key as keyof EventItem] : "";

                return (
                  <div key={idx} className="flex">
                    <strong
                      className="shrink-0 text-right mr-2 overflow-hidden text-ellipsis whitespace-nowrap"
                      style={{ width: `${labelWidthPx}px` }}
                    >
                      <Tooltip title={label}>{label}：</Tooltip>
                    </strong>

                    <div className="flex-1 break-words whitespace-pre-wrap">
                      {value !== undefined && value !== null && value !== ""
                        ? String(value)
                        : "—"}
                    </div>
                  </div>
                );
              })}
            </Splitter.Panel>
            <Splitter.Panel defaultSize="76%" min="60%">
              <ProcessingGraph
                key={graphKey}
                nodeflowsJson={currentRow.nodeflows}
              />
            </Splitter.Panel>
          </Splitter>
        ) : (
          <p>暂无详情数据</p>
        )}
      </Modal>
    </div>
  );
};

export default TableBox;
